package com.eairlv.route.agent.swagger;

import com.alibaba.fastjson.JSON;
import com.eairlv.route.agent.utils.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author eairlv
 * @description
 * @date 10:01 2019/8/28
 */
@Slf4j
@Primary
@Component
public class DocumentationConfig implements SwaggerResourcesProvider {

    /**
     * 集群群注册中心分隔符
     */
    private static final String COMMA = ",";

    /**
     * Swagger版本
     */
    public static final String SWAGGER_VERSION = "2.0";

    @Value("${eureka.client.service-url.defaultZone}")
    private String eurekaUrl;

    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 构建swagger数据结构
     * @return
     */
    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        try {
            ApplicationsResponse appsResponse = JSON.parseObject(restTemplate.getForEntity(buildAppsUrl(), String.class).getBody(), ApplicationsResponse.class);
            if (appsResponse != null){
                appsResponse.getApplications().getApplication().forEach(e -> {
                    if (!applicationName.equalsIgnoreCase(e.getName())) {
                        try {
                            resources.add(swaggerResource(e.getName().toLowerCase(), buildApiDocsLocation(e)));
                        } catch (Exception ex) {
                            log.warn("build swaggerResource catch exception: {}", LogUtil.getExceptionMessage(ex));
                        }
                    }
                });
            }
        } catch (Exception e) {
            log.warn("catch exception: {}", LogUtil.getExceptionMessage(e));
        }
        return resources.stream().sorted(Comparator.comparing(SwaggerResource::getName)).collect(Collectors.toList());
    }

    /**
     * 构建eureka获取所有服务信息的地址
     * @return
     */
    private String buildAppsUrl() {
        if (eurekaUrl.contains(COMMA)) {
            eurekaUrl = eurekaUrl.split(COMMA)[0];
        }
        return eurekaUrl + "/apps";
    }

    /**
     * 构建微服务Swagger地址
     * @param application
     * @return
     */
    private String buildApiDocsLocation(Application application) {
        return "/" + application.getName().toLowerCase() + "/v2/api-docs";
    }

    /**
     * 构建Swagger对象
     * @param name
     * @param location
     * @return
     */
    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(SWAGGER_VERSION);
        return swaggerResource;
    }
}
